﻿#region using
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Windows.Threading;
using System.Windows.Markup;
using Microsoft.Win32;
using Microsoft.Surface.Presentation;
using Microsoft.Surface.Presentation.Controls;
using Microsoft.Surface.Presentation.Input;
using System.Xml;
using System.Globalization;
using System.IO;
using System.Timers;
using System.ComponentModel;
using Ab2d.Common.ReaderWmf;
using System.Windows.Forms;
using System.Collections;
using System.Windows.Media.Animation;
#endregion
namespace MultiTouchDemonstrator
{
    /// <summary>
    /// Interaction logic for MapArea.xaml
    /// </summary>
    public partial class MapArea : System.Windows.Controls.UserControl
    {
        #region Private members
        
        private Symbol symbol = null;
        /// <summary>
        /// La bibliotheque des symboles
        /// </summary>
        private LibraryContainer m_libraryContainer;
        /// <summary>
        /// Le slider qui realise le zoom lors du Drag des symboles dans le plan
        /// </summary>
        private SurfaceSlider slider_map;

        /// <summary>
        /// 
        /// </summary>
        private RoutedPropertyChangedEventArgs<double> zoomSlide;
        /// <summary>
        /// L'echelle de zoom realiser sur le plan
        /// </summary>
        private Point m_zoom = new Point(1, 1);
        /// <summary>
        /// Le timer responsable de gerer les evenements du double click
        /// </summary>
        private System.Windows.Forms.Timer doubleClickTimer = new System.Windows.Forms.Timer();
        /// <summary>
        /// Un booleen mis a vrai si on click une premiere fois sur un symbole du plan
        /// </summary>
        private bool isFirstClick = true;
        /// <summary>
        /// Une image correspondant au symbole selectionne lors d'un premier click
        /// Elle est comparee a l'image lors d'un second click afin de ne supprimer que les images surlesquelles on a double clique
        /// </summary>
        private Image elementDelete = null;
        /// <summary>
        /// Le temps ecoule lors d'un double click
        /// </summary>
        private int milliseconds = 0;
        /// <summary>
        /// Permet de bloquer le zoom du plan avec le slider avant l'evenement DragEnter
        /// </summary>
        /// 
        
        private bool slide_do_zoom = false;
        private Canvas Map = null;
        #endregion
        public MapArea()
        {
            InitializeComponent();
            CreateNewCanvas();

        }
        public void CreateNewCanvas()
        {
            gridMap.Children.Clear();
            Map = new Canvas();
            gridMap.Children.Add(Map);
            Map.Height = 1000;
            Map.Width = 2000;
            SurfaceDragDrop.AddDragEnterHandler(Map,Map_DragEnter);
            SurfaceDragDrop.AddPreviewDropHandler(Map, Map_PreviewDrop);
            Map.IsManipulationEnabled = true;
            Map.ClipToBounds = true;
            Map.AllowDrop = true;
            SurfaceDragDrop.AddDropHandler(Map, Map_Drop);
            Map.PreviewTouchDown += DoubleClickTimer;
        }
        #region Properties
        public LibraryContainer SymbolContainer
        {
            get { return m_libraryContainer; }
            set { m_libraryContainer = value; }
        }

        public SurfaceSlider SliderMap
        {
            get { return slider_map; }
            set { slider_map = value; }
        }

        public bool SliderDoZoom
        {
            get { return slide_do_zoom; }
            set { slide_do_zoom = value; }
        }
       
        public Canvas MapCanvas
        {
            get { return Map; }
            set { Map = value; }
        }
        public Point ZoomCanvas
        {
            get { return m_zoom; }
            set { m_zoom = value; }
        }
        public Grid GridMap
        {
            get { return gridMap; }
            set { gridMap = value; }
        }

        public RoutedPropertyChangedEventArgs<double> ZoomItem
        {
            get { return zoomSlide; }
            set { zoomSlide = value; }
        }

        #endregion
        #region Symbol Drag and Drop

       
        /// <summary>
        /// procedure applee lors de l'ajout d'un symbole dans un plan
        /// </summary>
        /// <param name="sender">canvas : le plan</param>
        /// <param name="e"></param>
        private void Map_Drop(object sender, SurfaceDragDropEventArgs e)
        {
            ItemsControl itemsControl = sender as ItemsControl;
            if (symbol == null) 
            {
                symbol = new Symbol();
            }
            symbol.AddSymbol(Map,m_libraryContainer,zoomSlide,m_zoom,(string)e.Cursor.Data, e.Cursor.GetPosition(Map).X, e.Cursor.GetPosition(Map).Y, true);
          
        }
        
        private void Map_DragEnter(object sender, SurfaceDragDropEventArgs e)
        {
            slider_map.Value = ZoomCanvas.X * 100;
            slide_do_zoom = true;
            slider_map.Visibility = Visibility.Visible;
        }

        private void Map_PreviewDrop(object sender, SurfaceDragDropEventArgs e)
        {
            slide_do_zoom = false;
            slider_map.Visibility = Visibility.Hidden;
        }
        #endregion
        #region Symbol manipulation
        /// <summary>
        /// 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
      
        #endregion

        //Region consacree a la suppresion des symboles presents sur le plan
        #region Symbol delete

        /// <summary>
        /// Cette methode permet de supprimer les symboles lors d'un double touch click en utilisant une animation
        /// C'est un gestionnaire d'evenements qui est delenche lors d'un touch click sur un symbole
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void DoubleClickTimer(object sender, TouchEventArgs e)
        {
            
            doubleClickTimer.Interval = 200;
            doubleClickTimer.Tick += new EventHandler(doubleClickTimer_Tick);

            // Partie consacree au premier touch click 
            if (isFirstClick)
            {
                isFirstClick = false;
                elementDelete = null;
                System.Windows.DataObject obj = new System.Windows.DataObject();
                FrameworkElement findSource = e.OriginalSource as FrameworkElement;
                while (elementDelete == null && findSource != null)
                {
                    if ((elementDelete = findSource as Image) == null)
                    {
                        findSource = VisualTreeHelper.GetParent(findSource) as FrameworkElement;
                    }
                }

                // lance le double click timer
                doubleClickTimer.Start();
            }

            // Partie consacree au deuxieme touch click 
            else
            {
                System.Windows.DataObject obj = new System.Windows.DataObject();
                FrameworkElement findSource = e.OriginalSource as FrameworkElement;
                Image draggedElement = null;
                while (draggedElement == null && findSource != null)
                {
                    if ((draggedElement = findSource as Image) == null)
                    {
                        findSource = VisualTreeHelper.GetParent(findSource) as FrameworkElement;
                    }
                }

                if (draggedElement == null)
                {
                    return;
                }
                NameScope.SetNameScope(this, new NameScope());
                draggedElement.Name = "ImageAsuppr";
                this.RegisterName(draggedElement.Name, draggedElement);
                DoubleAnimation opacityAnimation = new DoubleAnimation();
                opacityAnimation.From = 1.0;
                opacityAnimation.To = 0.0;
                opacityAnimation.Duration = new Duration(TimeSpan.FromSeconds(0.5));
                Storyboard animationSuppr = new Storyboard();
                animationSuppr.Children.Add(opacityAnimation);
                //opacityAnimation.AutoReverse = true;
                Storyboard.SetTargetName(opacityAnimation, draggedElement.Name);
                Storyboard.SetTargetProperty(
                    opacityAnimation, new PropertyPath(Image.OpacityProperty));

                if (elementDelete == draggedElement)
                {
                    animationSuppr.Completed += new EventHandler(animationSuppr_Completed);
                    //L'animation est lancee
                    animationSuppr.Begin(this);
                }
            }
        }
        /// <summary>
        /// Ce gestionnaire d'evenement est lance lorsque l'animation de la suppression d'un symbole est termine
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        void animationSuppr_Completed(object sender, EventArgs e)
        {
            if (elementDelete != null)
                Map.Children.Remove(elementDelete);
        }

        /// <summary>
        /// Ce gestionnaire d'evenement est declenche lorsque l'intervalle du timer defini s'est écoulée et le timer est activée.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        void doubleClickTimer_Tick(object sender, EventArgs e)
        {
            milliseconds += 200;

            //La minuterie a atteint la limite d'un double click normale
            if (milliseconds >= SystemInformation.DoubleClickTime)
            {
                doubleClickTimer.Stop();

                //Permet au gestionnaire d'evenement du TouchDown de pouvoir cliquer a nouveau
                isFirstClick = true;
                milliseconds = 0;
            }
        }
        #endregion
        
        

    
    }
}
